
<template>
  <div class="change-avatar">
    <CropperAvatar
      v-if="showCropper"
      ref="cropperRef"
      :btnProps="{ preIcon: 'ant-design:cloud-upload-outlined' }"
      :showBtn="false"
      :value="img"
      :key="cropperKey"
      width="120px"
      @change="handelUpload"
    />
  </div>
</template>
<script lang="ts" setup>
import { propTypes } from '@/utils/propTypes'
import { CropperAvatar } from '@/components/Cropper'
import { useUserStore } from '@/store/modules/user'
import request from "@/config/axios"
import CryptoJS from 'crypto-js'
import { ref, watch } from 'vue'

defineOptions({ name: 'UserAvatar' })

const props = defineProps({
  img: propTypes.string.def('')
})

const emit = defineEmits(['update:headPhoto'])

const userStore = useUserStore()
const cropperKey = ref(Date.now()) // 用于强制重新渲染组件的key
const showCropper = ref(true) // 控制组件显示隐藏

// 监听img属性变化，强制重新渲染组件
watch(() => props.img, () => {
  refreshComponent()
})

// 刷新组件的方法
const refreshComponent = () => {
  showCropper.value = false
  cropperKey.value = Date.now()
  setTimeout(() => {
    showCropper.value = true
  }, 0)
}

const cropperRef = ref()
const handelUpload = async ( { data, filename } ) => {
  const ossname = await generateFileName(data, filename);
  const res = await uploadAvatar({ file: data, path: 'images/advisor/avtar/' + ossname })
  cropperRef.value.close()
  // await userStore.setUserAvatarAction(res.data)
  
  // 通知父组件更新headPhoto
  emit('update:headPhoto', res.data)
  
  refreshComponent() // 上传完成后重新渲染组件
}

const uploadAvatar = (data) => {
  return request.upload({ url: '/infra/file/upload', data: data })
}

/**
 * 生成文件名称（使用算法SHA256）
 * @param file 要上传的文件
 * @param filename 文件名称
 */
async function generateFileName(file: File, filename: String) {
  // 读取文件内容
  const data = await file.arrayBuffer()
  const wordArray = CryptoJS.lib.WordArray.create(data)
  // 计算SHA256
  const sha256 = CryptoJS.SHA256(wordArray).toString()
  // 拼接后缀
  const ext = filename.substring(filename.lastIndexOf('.'))
  return `${sha256}${ext}`
}

</script>

<style lang="scss" scoped>
.change-avatar {
  img {
    display: block;
    margin-bottom: 15px;
    border-radius: 50%;
  }
  
  :deep(.user-info-head) {
    transition: all 0.3s;
    
    &:hover::after {
      width: 120px;
      height: 120px;
      font-size: 26px;
      line-height: 120px;
      color: #fff;
      background: rgba(0, 0, 0, 0.6);
      content: '+';
      text-align: center;
    }
  }
}
</style>
